package com.smasher.location.proxy;

import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;

import androidx.activity.ComponentActivity;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;

import com.smasher.location.eums.LocationMode;
import com.smasher.location.listener.onLocationListener;

import java.lang.ref.WeakReference;
import java.util.Map;

public class LocationHelper implements DefaultLifecycleObserver {

    public static final String TAG = "LocationHelper";
    private final WeakReference<Context> referenceContext;

    private LocationProxy mLocationProxy;
    private final ActivityResultLauncher<String[]> mPermissionLauncher;
    private final ActivityResultContracts.RequestMultiplePermissions mRequestPermission =
            new ActivityResultContracts.RequestMultiplePermissions();
    private final ActivityResultCallback<Map<String, Boolean>> mPermissionCallback = o -> {
        if (Boolean.TRUE.equals(o.get(android.Manifest.permission.ACCESS_FINE_LOCATION)) ||
                Boolean.TRUE.equals(o.get(android.Manifest.permission.ACCESS_COARSE_LOCATION))) {
            mLocationProxy.start();
        }

    };

    public LocationHelper(ComponentActivity activity) {
        Lifecycle registry = activity.getLifecycle();
        attachContext(activity, registry);
        referenceContext = new WeakReference<>(activity);
        mPermissionLauncher = activity.registerForActivityResult(mRequestPermission, mPermissionCallback);
    }

    public LocationHelper(Fragment fragment) {
        Context context = fragment.requireContext();
        Lifecycle registry = fragment.getLifecycle();
        attachContext(context, registry);
        referenceContext = new WeakReference<>(context);
        mPermissionLauncher = fragment.registerForActivityResult(mRequestPermission, mPermissionCallback);
    }


    private void attachContext(Context context, Lifecycle registry) {
        mLocationProxy = new LocationProxy();
        mLocationProxy.init(context);
        registry.addObserver(this);
    }

    public boolean checkPermission() {
        if (referenceContext.get() != null) {
            int fineLocation = ContextCompat.checkSelfPermission(referenceContext.get(), android.Manifest.permission.ACCESS_FINE_LOCATION);
            int coarseLocation = ContextCompat.checkSelfPermission(referenceContext.get(), android.Manifest.permission.ACCESS_COARSE_LOCATION);
            if (coarseLocation == PackageManager.PERMISSION_GRANTED || fineLocation == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                String[] permissions = new String[]{
                        android.Manifest.permission.ACCESS_FINE_LOCATION,
                        android.Manifest.permission.ACCESS_COARSE_LOCATION
                };
                mPermissionLauncher.launch(permissions);
            }
        }
        return false;
    }

    public void setMode(LocationMode mode) {
        mLocationProxy.setMode(mode);
    }

    public void setLocationListener(onLocationListener onLocationListener) {
        mLocationProxy.setLocationListener(onLocationListener);
    }

    @Override
    public void onCreate(@NonNull LifecycleOwner owner) {
        Log.d(TAG, "onCreate: ");
    }

    @Override
    public void onStart(@NonNull LifecycleOwner owner) {
        Log.d(TAG, "onStart: ");
        if (checkPermission()) {
            mLocationProxy.start();
        }
    }

    @Override
    public void onStop(@NonNull LifecycleOwner owner) {
        Log.d(TAG, "onStop: ");
        mLocationProxy.stop();
    }

    @Override
    public void onDestroy(@NonNull LifecycleOwner owner) {
        Log.d(TAG, "onDestroy: ");
        referenceContext.clear();
        mLocationProxy.release();
    }


}
